import type { IHttpResponse, IObject } from '@/utils/hookFetchHttp';
import hookFetchHttp from '@/utils/hookFetchHttp';

/**
 * 基于hook-fetch的通用CRUD服务
 */
export default {
  /**
   * 删除
   * @param path 请求路径
   * @param params 请求参数
   * @returns Promise<IHttpResponse>
   */
  delete(path: string, params: IObject): Promise<IHttpResponse> {
    return hookFetchHttp({
      url: path,
      method: 'DELETE',
      body: params,
    });
  },

  /**
   * GET请求
   * @param path 请求路径
   * @param params 查询参数
   * @param headers 自定义请求头
   * @returns Promise<IHttpResponse>
   */
  get(path: string, params?: IObject, headers?: IObject): Promise<IHttpResponse> {
    return new Promise((resolve, reject) => {
      hookFetchHttp({
        url: path,
        method: 'GET',
        params,
        headers,
      })
        .then(resolve)
        .catch((error) => {
          // 忽略重复请求错误
          if (error.message !== '-999') {
            reject(error);
          }
        });
    });
  },

  /**
   * PUT请求
   * @param path 请求路径
   * @param params 请求体数据
   * @param headers 自定义请求头
   * @returns Promise<IHttpResponse>
   */
  put(path: string, params?: IObject, headers?: IObject): Promise<IHttpResponse> {
    return hookFetchHttp({
      url: path,
      method: 'PUT',
      body: params,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        ...headers,
      },
    });
  },

  /**
   * 通用POST方法
   * @param path 请求路径
   * @param body 请求体数据
   * @param headers 自定义请求头
   * @returns Promise<IHttpResponse>
   */
  post(path: string, body?: IObject, headers?: IObject): Promise<IHttpResponse> {
    return hookFetchHttp({
      url: path,
      method: 'POST',
      body,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        ...headers,
      },
    });
  },

  /**
   * 通过接口下载文件
   * @param path 请求路径
   * @param params 请求参数
   * @param filename 文件名
   * @param method 请求方法
   * @returns Promise<void>
   */
  async download(
    path: string,
    params?: IObject,
    filename?: string,
    method: 'GET' | 'POST' = 'GET'
  ): Promise<void> {
    const config: any = {
      url: path,
      method,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
      },
    };

    if (method.toUpperCase() === 'POST') {
      config.body = params;
    } else {
      config.params = params;
    }

    try {
      // 使用原生fetch处理blob响应
      const response = await fetch(config.url, {
        method: config.method,
        headers: config.headers,
        body: config.body ? JSON.stringify(config.body) : undefined,
      });

      if (!response.ok) {
        throw new Error(`下载失败: ${response.status}`);
      }

      const blob = await response.blob();
      const downloadFilename = filename || params?.filename || new Date().getTime().toString();

      // 创建下载链接
      const a = document.createElement('a');
      const url = URL.createObjectURL(blob);
      a.href = url;
      a.download = downloadFilename;
      a.style.display = 'none';
      
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      
      // 释放URL对象
      URL.revokeObjectURL(url);
    } catch (error) {
      console.error('下载文件失败:', error);
      throw error;
    }
  },

  /**
   * 通过文件地址下载文件
   * @param url 文件URL
   * @param filename 文件名
   * @returns Promise<void>
   */
  async downloadFile(url: string, filename: string): Promise<void> {
    try {
      const response = await fetch(url);
      
      if (!response.ok) {
        throw new Error(`下载失败: ${response.status}`);
      }

      const blob = await response.blob();

      // 兼容IE10
      if ((window.navigator as any).msSaveOrOpenBlob) {
        (window.navigator as any).msSaveBlob(blob, filename);
        return;
      }

      // 现代浏览器
      const downloadUrl = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.style.display = 'none';
      a.href = downloadUrl;
      a.download = filename;
      
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      
      // 释放URL对象
      URL.revokeObjectURL(downloadUrl);
    } catch (error) {
      console.error('下载文件失败:', error);
      throw error;
    }
  },

  /**
   * 上传文件
   * @param path 上传路径
   * @param file 文件对象或FormData
   * @param onProgress 上传进度回调
   * @returns Promise<IHttpResponse>
   */
  async upload(
    path: string,
    file: File | FormData,
    onProgress?: (progress: number) => void
  ): Promise<IHttpResponse> {
    const formData = file instanceof FormData ? file : new FormData();
    
    if (file instanceof File) {
      formData.append('file', file);
    }

    // 使用XMLHttpRequest支持上传进度
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      
      // 设置上传进度监听
      if (onProgress) {
        xhr.upload.addEventListener('progress', (event) => {
          if (event.lengthComputable) {
            const progress = Math.round((event.loaded / event.total) * 100);
            onProgress(progress);
          }
        });
      }

      xhr.addEventListener('load', () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const response = JSON.parse(xhr.responseText);
            resolve(response);
          } catch (error) {
            reject(new Error('响应解析失败'));
          }
        } else {
          reject(new Error(`上传失败: ${xhr.status}`));
        }
      });

      xhr.addEventListener('error', () => {
        reject(new Error('上传失败'));
      });

      // 设置请求头（不设置Content-Type，让浏览器自动设置boundary）
      const token = localStorage.getItem('token') || sessionStorage.getItem('token');
      if (token) {
        xhr.setRequestHeader('token', token);
      }

      xhr.open('POST', path);
      xhr.send(formData);
    });
  },
};